package com.wenjie.original.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.mybatisflex.core.query.QueryWrapper;
import com.wenjie.original.entity.SysDbEnum;
import com.wenjie.original.entity.SysDbField;
import com.wenjie.original.entity.SysDbTable;
import com.wenjie.original.entity.table.SysDbEnumTableDef;
import com.wenjie.original.entity.table.SysDbFieldTableDef;
import com.wenjie.original.entity.vo.SysDbField.SysDbFieldByAddEnumsVo;
import com.wenjie.original.entity.vo.SysDbField.SysDbFieldBySelEnumsVo;
import com.wenjie.original.entity.vo.SysDbField.SysDbFieldUpOrAddVo;
import com.wenjie.original.entity.vo.SysDbField.SysDbFieldVo;
import com.wenjie.original.flex_config.baseInterface.Cus_ServiceImp;
import com.wenjie.original.mapper.SysDbFieldMapper;
import com.wenjie.original.service.ISysDbEnumService;
import com.wenjie.original.service.ISysDbFieldService;
import com.wenjie.original.service.ISysDbTableService;
import com.wenjie.service.ICodeTemplateHandle;
import com.wenjie.vo.gen.TableInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 字段映射 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-09-06 15:31:17
 */
@Service
public class SysDbFieldServiceImpl extends Cus_ServiceImp<SysDbFieldMapper, SysDbField> implements ISysDbFieldService {


    @Autowired
    private ISysDbTableService sysDbTableService;

    @Autowired
    private ISysDbFieldService sysDbFieldService;

    @Autowired
    private ISysDbEnumService sysDbEnumService;

    @Autowired
    private ICodeTemplateHandle codeTemplateHandle;


    @Override
    public List<SysDbField> listBySysDbTableId(Long sysDbTableId) {
        List<SysDbField> list = this.list(QueryWrapper.create().where(SysDbFieldTableDef.SYS_DB_FIELD.SYS_DB_TABLE_ID.eq(sysDbTableId)));
        return list;
    }

    @Override
    public SysDbField getByFieldName(Long sysDbTableId, String fieldName) {
        return this.getOne(QueryWrapper.create().where(SysDbFieldTableDef.SYS_DB_FIELD.FIELD_NAME.eq(fieldName).and(SysDbFieldTableDef.SYS_DB_FIELD.SYS_DB_TABLE_ID.eq(sysDbTableId))));
    }

    @Override
    public List<SysDbFieldVo.ResVo> cusListAll(Long sysDbTableId) {
        SysDbTable sysDbTable = sysDbTableService.getById(sysDbTableId);

        List<SysDbFieldVo.ResVo> matchs = new ArrayList<>(); // sysdbtbale匹配的数据
        List<SysDbFieldVo.ResVo> tables = new ArrayList<>(); // sysdbtbale没有匹配的数据
        List<SysDbFieldVo.ResVo> realDb = new ArrayList<>(); // 当前真实数据库没有匹配的数据


        // 记录的全部表信息
        List<SysDbField> list = this.listBySysDbTableId(sysDbTableId);
        List<SysDbFieldVo.ResVo> rests = new ArrayList<>();
        for (SysDbField sysDbField : list) {
            SysDbFieldVo.ResVo bean = BeanUtil.toBean(sysDbField, SysDbFieldVo.ResVo.class);
            bean.setType("记录");
            bean.setSysDbEnums(sysDbEnumService.listBySysdbFieldId(bean.getSysDbFieldId()));
            rests.add(bean);
        }

        // 查看一下数据库的全部表信息
        List<TableInfo.Column> columns = codeTemplateHandle.getTableInfo(sysDbTable.getTableName()).getColumns();

        // 查看一下sysdbtbale中 匹配到和没匹配到的信息
        Set<String> tableNameSet = new HashSet<>();
        outerLoop:
        for (SysDbFieldVo.ResVo rest : rests) {
            String tableName = rest.getFieldName();
            for (TableInfo.Column column : columns) {
                if (column.getName().equals(tableName)) {
                    rest.setIsMatch(true);
                    rest.setDbComment(column.getComment());
                    matchs.add(rest);
                    tableNameSet.add(tableName);
                    continue outerLoop;
                }
            }
            rest.setIsMatch(false);
            tables.add(rest);
        }

        // 查看一下没有匹配到的真实表信息
        for (TableInfo.Column column : columns) {
            if (!tableNameSet.contains(column.getName())) {
                SysDbFieldVo.ResVo resVo = new SysDbFieldVo.ResVo();
                resVo.setSysDbFieldId(sysDbTableId);
                resVo.setFieldName(column.getName());
                resVo.setFieldType(column.getType());

                resVo.setDbComment(column.getComment());
                resVo.setIsMatch(false);
                resVo.setType("真实字段");
                realDb.add(resVo);
            }
        }

        matchs.addAll(tables);
        matchs.addAll(realDb);
        return matchs;
    }

    @Override
    public void syncAll(Long sysDbTableId) {
        SysDbTable sysDbTable = sysDbTableService.getById(sysDbTableId);
        List<TableInfo.Column> columns = codeTemplateHandle.getTableInfo(sysDbTable.getTableName()).getColumns(); // 表的真实字段
        for (TableInfo.Column column : columns) {
            sync(sysDbTable, column.getName(), columns);
        }
    }


    @Override
    public void sync(Long sysDbTableId, String fieldName) {
        SysDbTable sysDbTable = sysDbTableService.getById(sysDbTableId);
        List<TableInfo.Column> columns = codeTemplateHandle.getTableInfo(sysDbTable.getTableName()).getColumns(); // 表的真实字段
        sync(sysDbTable, fieldName, columns);
    }

    @Override
    @Transactional
    public void addEnums(SysDbFieldByAddEnumsVo sysDbFieldByAddEnumsVo) {

        SysDbField sysDbField = sysDbFieldService.getById(sysDbFieldByAddEnumsVo.getSysDbFieldId());
        SysDbTable sysDbTable = sysDbTableService.getById(sysDbField.getSysDbTableId());

        // 在全局的enum上添加 字段的id
        for (SysDbEnum sysDbEnum : sysDbFieldByAddEnumsVo.getSysDbEnums()) {

            sysDbEnum.setSysDbFieldId(sysDbField.getSysDbFieldId());
            sysDbEnum.setSysDbTableId(sysDbTable.getSysDbTableId());

            sysDbEnum.setTableName(sysDbTable.getTableName());
            sysDbEnum.setFieldName(sysDbField.getFieldName());
            sysDbEnum.setSysDbEnumId(null);
        }

        sysDbEnumService.remove(QueryWrapper.create().where(SysDbEnumTableDef.SYS_DB_ENUM.SYS_DB_FIELD_ID.eq(sysDbFieldByAddEnumsVo.getSysDbFieldId())));
        sysDbEnumService.saveBatch(sysDbFieldByAddEnumsVo.getSysDbEnums());
    }

    @Override
    public List<SysDbEnum> listEnums(SysDbFieldBySelEnumsVo sysDbFieldBySelEnumsVo) {
        List<SysDbEnum> sysDbEnums = null;

        try {
            // 查询一下数据值
            SysDbTable sysDbTable = sysDbTableService.getByTableName(sysDbFieldBySelEnumsVo.getTableName());
            SysDbField sysDbField = sysDbFieldService.getOne(QueryWrapper.create().where(SysDbFieldTableDef.SYS_DB_FIELD.FIELD_NAME.eq(sysDbFieldBySelEnumsVo.getFieldName()).and(SysDbFieldTableDef.SYS_DB_FIELD.SYS_DB_TABLE_ID.eq(sysDbTable.getSysDbTableId()))));

            sysDbEnums = sysDbEnumService.listBySysdbFieldId(sysDbField.getSysDbFieldId());
        } catch (Exception e) {
            return null;
        }
        return sysDbEnums;
    }

    @Override
    public JSONObject AllEnums() {

        JSONObject rest = new JSONObject();

        List<SysDbEnum> list = sysDbEnumService.list();
        for (SysDbEnum sysDbEnum : list) {
            String tableName = sysDbEnum.getTableName();
            String fieldName = sysDbEnum.getFieldName();

            if (rest.getJSONObject(tableName) == null) {
                rest.set(tableName, new JSONObject());
            }
            if (rest.getJSONObject(tableName).getJSONArray(fieldName) == null) {
                rest.getJSONObject(tableName).set(fieldName, new JSONArray());
            }
            rest.getJSONObject(tableName).getJSONArray(fieldName).add(sysDbEnum);
        }

        return rest;
    }

    @Override
    public List<SysDbField> getbyTableId(Long sysTableId) {
        return this.list(QueryWrapper.create().where(SysDbFieldTableDef.SYS_DB_FIELD.SYS_DB_TABLE_ID.eq(sysTableId)));
    }

    @Override
    @Transactional
    public void cusUpdateById(SysDbFieldUpOrAddVo.UpVo upVo) {
        sysDbEnumService.updateChain().set(SysDbEnumTableDef.SYS_DB_ENUM.FIELD_NAME, upVo.getFieldName()).where(SysDbEnumTableDef.SYS_DB_ENUM.SYS_DB_FIELD_ID.eq(upVo.getSysDbFieldId())).update();

        this.updateById(upVo);
    }

    @Override
    public void cusRemoveById(Long sysDbFieldId) {
        sysDbEnumService.remove(QueryWrapper.create().where(SysDbEnumTableDef.SYS_DB_ENUM.SYS_DB_FIELD_ID.eq(sysDbFieldId)));
        this.removeById(sysDbFieldId);
    }


    private void sync(SysDbTable sysDbTable, String fieldName, List<TableInfo.Column> columns) {
        // 找到真实的字段信息
        TableInfo.Column realColumn = null;
        for (TableInfo.Column column : columns) {
            if (column.getName().equals(fieldName)) {
                realColumn = column;
                break;
            }
        }

        try {
            SysDbField sysDbField = this.getByFieldName(sysDbTable.getSysDbTableId(), fieldName);

            if (realColumn == null) {
                // 什么也不管
            } else {
                sysDbField.setComment(realColumn.getComment());
                sysDbField.setFieldType(realColumn.getType());
                this.updateById(sysDbField);
            }
        } catch (Exception e) {

            if (realColumn == null) {
                throw new RuntimeException("传参不正确");
            } else {
                SysDbField sysDbField = new SysDbField();
                sysDbField.setSysDbTableId(sysDbTable.getSysDbTableId());
                sysDbField.setFieldName(realColumn.getName());
                sysDbField.setFieldType(realColumn.getType());
                sysDbField.setComment(realColumn.getComment());
                this.save(sysDbField);
            }
        }

    }


}



